package com.spring.springboot.sys.controller;

import cn.hutool.crypto.SecureUtil;
import com.spring.springboot.sys.core.config.SecurityConfigProperties;
import com.spring.springboot.sys.core.constant.RedisConstants;
import com.spring.springboot.sys.core.enums.RequestErrorEnum;
import com.spring.springboot.sys.core.model.Result;
import com.spring.springboot.sys.core.model.UserInfo;
import com.spring.springboot.sys.jwt.JwtTokenUtil;
import com.spring.springboot.sys.util.RedisUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 权限token 控制层
 *
 * @author 宋义州
 * @date 2021/12/9 下午4:10
 */
@Slf4j
@RestController
@RequestMapping("/authToken")
public class AuthTokenController {

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private SecurityConfigProperties securityConfigProperties;

    /**
     * 刷新 权限token
     */
    @PostMapping("/refresh")
    public Result refresh(HttpServletRequest request) {
        String token = request.getHeader(securityConfigProperties.getHeader());
        if (StringUtils.isBlank(token)) {
            return Result.error(RequestErrorEnum.LOGIN_EXPIRE.getCode(), RequestErrorEnum.LOGIN_EXPIRE.getMessage());
        }
        token = token.substring(this.securityConfigProperties.getPrefix().length());
        try {
            Claims claims = jwtTokenUtil.getClaimsFromToken(token);
            UserInfo userInfo = new UserInfo();
            userInfo.setAccount(claims.getSubject());
            // 生成jwt
            String authToken = this.securityConfigProperties.getPrefix() + jwtTokenUtil.generateToken(userInfo);
            // 将token存放到redis中
            redisUtils.set(String.format(RedisConstants.LOGIN_TOKEN_PREFIX, userInfo.getAccount()), SecureUtil.md5(authToken), this.securityConfigProperties.getExpiration());
            return Result.success("token刷新成功！", authToken);
        } catch (Exception e) {
            log.warn("刷新token出现异常：{}", token, e);
            return Result.error(RequestErrorEnum.LOGIN_EXPIRE.getCode(), RequestErrorEnum.LOGIN_EXPIRE.getMessage());
        }
    }
}
